package com.example.zipstream;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * ZipEntry 是表示 ZIP 文件中一个条目的类，它包含了有关该条目的元数据（如文件名、文件大小、压缩方法等）。
 * 在 ZipOutputStream 中，你使用 ZipEntry 来指定一个新的条目，而在 ZipInputStream 中，它用于获取当前条目的详细信息。
 * getName()：返回条目的名称（文件名）。
 * getSize()：返回原始文件的大小。
 * getCompressedSize()：返回压缩后的大小。
 * getMethod()：返回压缩方法（ZipEntry.DEFLATED 或 ZipEntry.STORED）。
 */

/**
 * ZipOutputStream 需要显式地使用 putNextEntry() 来添加条目，而每个条目被写入后需要调用 closeEntry() 来结束当前条目的写入。
 * ZipInputStream 通过 getNextEntry() 自动读取 ZIP 文件中的每个条目，并通过 closeEntry() 结束条目的读取。
 */

public class ZipStreamDemo3 {
    public static void main(String[] args) throws IOException {
        /**
         * 压缩流
         */
        //1.创建File对象表示要压缩的文件夹
        File src = new File("zip/file");
        //2.创建File对象表示压缩包存放位置（压缩包的父级路径）
        File destParent = src.getParentFile();
        //3.创建File对象表示压缩包的路径
        File dest = new File(destParent, src.getName() + ".zip");
        //4.创建压缩流关联压缩包
        ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(dest));
        //5.获取src里面的每一个文件，变成ZipEntry对象，放入压缩包中
        toZip(src, zos, src.getName());
        //6.释放资源
        zos.close();
    }

    /**
     * 作用：获取src里面的每一个文件，变成ZipEntry对象，放入到压缩包中
     * 参数一：数据源
     * 参数二：压缩流
     * 参数三：压缩包内部的路径
     *
     * @param src
     * @param zos
     * @param name
     */
    public static void toZip(File src, ZipOutputStream zos, String name) throws IOException {
        //1.进入src文件夹
        File[] files = src.listFiles();
        //2.遍历数组
        for (File file : files) {
            if (file.isFile()) {
                //3.判断-文件，变成ZipEntry对象，放入到压缩包中
                ZipEntry entry = new ZipEntry(name + "/" + file.getName());
                zos.putNextEntry(entry);
                //读取文件中的数据，写到压缩包中
                FileInputStream in = new FileInputStream(file);
                int read = in.read();
                while (read != -1) {
                    zos.write(read);
                    read = in.read();
                }
                in.close();
                zos.closeEntry();
            } else {
                //4.判断-文件夹，递归
                toZip(file, zos, name + "/" + file.getName());
            }
        }
    }
}
